﻿#define Jinndev_DOTweenUtil
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
using DG.Tweening;
using DG.Tweening.Core;
using DG.Tweening.Plugins.Options;

namespace Jinndev {

    public static class DOTweenUtil {

        public static void DOKill(Object parent, string path) {
            Transform transform = CommonUtil.GetTransform(parent, path);
            if (transform != null) {
                transform.DOKill();
            }
        }

        public static void DOAnchorPos(Object parent, string path, float duration, Vector2 position, Ease ease = Ease.OutQuad) {
            RectTransform transform = CommonUtil.GetTransform(parent, path) as RectTransform;
            if (transform != null) {
                if (duration == 0) {
                    transform.anchoredPosition = position;
                }
                else {
                    transform.DOAnchorPos(position, duration).SetEase(ease);
                }
            }
        }

        public static void DOAnchorPosX(Object parent, string path, float duration, float x, Ease ease = Ease.OutQuad) {
            RectTransform transform = CommonUtil.GetTransform(parent, path) as RectTransform;
            if (transform != null) {
                if (duration == 0) {
                    Vector2 position = transform.anchoredPosition;
                    position.x = x;
                    transform.anchoredPosition = position;
                }
                else {
                    transform.DOAnchorPosX(x, duration).SetEase(ease);
                }
            }
        }

        public static void DOAnchorPosY(Object parent, string path, float duration, float y, Ease ease = Ease.OutQuad) {
            RectTransform transform = CommonUtil.GetTransform(parent, path) as RectTransform;
            if (transform != null) {
                if (duration == 0) {
                    Vector2 position = transform.anchoredPosition;
                    position.y = y;
                    transform.anchoredPosition = position;
                }
                else {
                    transform.DOAnchorPosY(y, duration).SetEase(ease);
                }
            }
        }

        public static void DOAnchorPos3D(Object parent, string path, float duration, Vector3 position, Ease ease = Ease.OutQuad) {
            RectTransform transform = CommonUtil.GetTransform(parent, path) as RectTransform;
            if (transform != null) {
                if (duration == 0) {
                    transform.anchoredPosition3D = position;
                }
                else {
                    transform.DOAnchorPos3D(position, duration).SetEase(ease);
                }
            }
        }

        public static void DOAnchorPosX3D(Object parent, string path, float duration, float x, Ease ease = Ease.OutQuad) {
            RectTransform transform = CommonUtil.GetTransform(parent, path) as RectTransform;
            if (transform != null) {
                if (duration == 0) {
                    Vector3 position = transform.anchoredPosition3D;
                    position.x = x;
                    transform.anchoredPosition3D = position;
                }
                else {
                    Vector3 position = transform.anchoredPosition3D;
                    position.x = x;
                    transform.DOAnchorPos3D(position, duration).SetEase(ease);
                }
            }
        }

        public static void DOAnchorPosY3D(Object parent, string path, float duration, float y, Ease ease = Ease.OutQuad) {
            RectTransform transform = CommonUtil.GetTransform(parent, path) as RectTransform;
            if (transform != null) {
                if (duration == 0) {
                    Vector3 position = transform.anchoredPosition3D;
                    position.y = y;
                    transform.anchoredPosition3D = position;
                }
                else {
                    Vector3 position = transform.anchoredPosition3D;
                    position.y = y;
                    transform.DOAnchorPos3D(position, duration).SetEase(ease);
                }
            }
        }

        public static void DOAnchorPosZ3D(Object parent, string path, float duration, float z, Ease ease = Ease.OutQuad) {
            RectTransform transform = CommonUtil.GetTransform(parent, path) as RectTransform;
            if (transform != null) {
                if (duration == 0) {
                    Vector3 position = transform.anchoredPosition3D;
                    position.z = z;
                    transform.anchoredPosition3D = position;
                }
                else {
                    Vector3 position = transform.anchoredPosition3D;
                    position.z = z;
                    transform.DOAnchorPos3D(position, duration).SetEase(ease);
                }
            }
        }

        public static void DOSizeDelta(Object parent, string path, float duration, Vector2 size, Ease ease = Ease.OutQuad) {
            RectTransform transform = CommonUtil.GetTransform(parent, path) as RectTransform;
            if (transform != null) {
                if (duration == 0) {
                    transform.sizeDelta = size;
                }
                else {
                    transform.DOSizeDelta(size, duration).SetEase(ease);
                }
            }
        }

        public static void DOSizeDeltaX(Object parent, string path, float duration, float x, Ease ease = Ease.OutQuad) {
            RectTransform transform = CommonUtil.GetTransform(parent, path) as RectTransform;
            if (transform != null) {
                Vector2 size = transform.sizeDelta;
                size.x = x;
                if (duration == 0) {
                    transform.sizeDelta = size;
                }
                else {
                    transform.DOSizeDelta(size, duration).SetEase(ease);
                }
            }
        }

        public static void DOSizeDeltaY(Object parent, string path, float duration, float y, Ease ease = Ease.OutQuad) {
            RectTransform transform = CommonUtil.GetTransform(parent, path) as RectTransform;
            if (transform != null) {
                Vector2 size = transform.sizeDelta;
                size.y = y;
                if (duration == 0) {
                    transform.sizeDelta = size;
                }
                else {
                    transform.DOSizeDelta(size, duration).SetEase(ease);
                }
            }
        }

        public static void DOLocalMove(Object parent, string path, float duration, Vector3 position, Ease ease = Ease.OutQuad) {
            Transform transform = CommonUtil.GetTransform(parent, path);
            if (transform != null) {
                if (duration == 0) {
                    transform.localPosition = position;
                }
                else {
                    transform.DOLocalMove(position, duration).SetEase(ease);
                }
            }
        }

        public static void DOLocalMoveX(Object parent, string path, float duration, float x, Ease ease = Ease.OutQuad) {
            Transform transform = CommonUtil.GetTransform(parent, path);
            if (transform != null) {
                if (duration == 0) {
                    Vector3 position = transform.localPosition;
                    position.x = x;
                    transform.localPosition = position;
                }
                else {
                    transform.DOLocalMoveX(x, duration).SetEase(ease);
                }
            }
        }

        public static void DOLocalMoveY(Object parent, string path, float duration, float y, Ease ease = Ease.OutQuad) {
            Transform transform = CommonUtil.GetTransform(parent, path);
            if (transform != null) {
                if (duration == 0) {
                    Vector3 position = transform.localPosition;
                    position.y = y;
                    transform.localPosition = position;
                }
                else {
                    transform.DOLocalMoveY(y, duration).SetEase(ease);
                }
            }
        }

        public static void DOLocalMoveZ(Object parent, string path, float duration, float z, Ease ease = Ease.OutQuad) {
            Transform transform = CommonUtil.GetTransform(parent, path);
            if (transform != null) {
                if (duration == 0) {
                    Vector3 position = transform.localPosition;
                    position.z = z;
                    transform.localPosition = position;
                }
                else {
                    transform.DOLocalMoveZ(z, duration).SetEase(ease);
                }
            }
        }

        public static void DOMove(Object parent, string path, float duration, Vector3 position, Ease ease = Ease.OutQuad) {
            Transform transform = CommonUtil.GetTransform(parent, path);
            if (transform != null) {
                if (duration == 0) {
                    transform.position = position;
                }
                else {
                    transform.DOMove(position, duration).SetEase(ease);
                }
            }
        }

        public static void DOMoveX(Object parent, string path, float duration, float x, Ease ease = Ease.OutQuad) {
            Transform transform = CommonUtil.GetTransform(parent, path);
            if (transform != null) {
                if (duration == 0) {
                    Vector3 position = transform.position;
                    position.x = x;
                    transform.position = position;
                }
                else {
                    transform.DOMoveX(x, duration).SetEase(ease);
                }
            }
        }

        public static void DOMoveY(Object parent, string path, float duration, float y, Ease ease = Ease.OutQuad) {
            Transform transform = CommonUtil.GetTransform(parent, path);
            if (transform != null) {
                if (duration == 0) {
                    Vector3 position = transform.position;
                    position.y = y;
                    transform.position = position;
                }
                else {
                    transform.DOMoveY(y, duration).SetEase(ease);
                }
            }
        }

        public static void DOMoveZ(Object parent, string path, float duration, float z, Ease ease = Ease.OutQuad) {
            Transform transform = CommonUtil.GetTransform(parent, path);
            if (transform != null) {
                if (duration == 0) {
                    Vector3 position = transform.position;
                    position.z = z;
                    transform.position = position;
                }
                else {
                    transform.DOMoveZ(z, duration).SetEase(ease);
                }
            }
        }

        public static void DOScale(Object parent, string path, float duration, float endValue, Ease ease = Ease.OutQuad) {
            Transform transform = CommonUtil.GetTransform(parent, path);
            if (transform != null) {
                transform.DOScale(endValue, duration).SetEase(ease);
            }
        }

        public static void DOScale(Object parent, string path, float duration, Vector3 endValue, Ease ease = Ease.OutQuad) {
            Transform transform = CommonUtil.GetTransform(parent, path);
            if (transform != null) {
                transform.DOScale(endValue, duration).SetEase(ease);
            }
        }

        public static void DOShakeScale(Object parent, string path, float duration, float strength = 1, int vibrato = 10, float randomness = 90, bool fadeOut = true, Ease ease = Ease.OutQuad) {
            Transform transform = CommonUtil.GetTransform(parent, path);
            if (transform != null) {
                transform.DOShakeScale(duration, strength, vibrato, randomness, fadeOut).SetEase(ease);
            }
        }

        public static void DOShakeScale(Object parent, string path, float duration, Vector3 strength, int vibrato = 10, float randomness = 90, bool fadeOut = true, Ease ease = Ease.OutQuad) {
            Transform transform = CommonUtil.GetTransform(parent, path);
            if (transform != null) {
                transform.DOShakeScale(duration, strength, vibrato, randomness, fadeOut).SetEase(ease);
            }
        }

        // <summary>
        /// 将ScrollRect滚动到指定百分比
        /// </summary>
        /// <param name="parent"></param>
        /// <param name="path"></param>
        /// <param name="index">从0开始</param>
        /// <param name="totalCount"></param>
        /// <param name="duration"></param>
        /// <param name="ease"></param>
        public static void DOScrollRectPercentX(Object parent, string path, int index, int totalCount, float duration, Ease ease = Ease.OutQuad) {
            ScrollRect scrollRect = CommonUtil.GetComponent<ScrollRect>(parent, path);
            if (scrollRect != null) {
                Vector2 size = scrollRect.content.rect.size;
                Vector2 viewSize = scrollRect.viewport.rect.size;

                float x = 1;
                if (totalCount > 0) {
                    x = Mathf.Clamp01((index * size.x / totalCount) / (size.x - viewSize.x));
                }

                if (duration == 0) {
                    Vector2 pos = scrollRect.normalizedPosition;
                    pos.x = x;
                    scrollRect.normalizedPosition = pos;
                }
                else {
                    scrollRect.DOHorizontalNormalizedPos(x, duration).SetEase(ease);
                }
            }
        }

        /// <summary>
        /// 将ScrollRect滚动到指定百分比
        /// </summary>
        /// <param name="parent"></param>
        /// <param name="path"></param>
        /// <param name="index">从0开始</param>
        /// <param name="totalCount"></param>
        /// <param name="duration"></param>
        /// <param name="ease"></param>
        public static void DOScrollRectPercentY(Object parent, string path, int index, int totalCount, float duration, Ease ease = Ease.OutQuad) {
            ScrollRect scrollRect = CommonUtil.GetComponent<ScrollRect>(parent, path);
            if (scrollRect != null) {
                Vector2 size = scrollRect.content.rect.size;
                Vector2 viewSize = scrollRect.viewport.rect.size;

                float y = 1;
                if (totalCount > 0) {
                    y = Mathf.Clamp01(1 - (index * size.y / totalCount) / (size.y - viewSize.y));
                }

                if (duration == 0) {
                    Vector2 pos = scrollRect.normalizedPosition;
                    pos.y = y;
                    scrollRect.normalizedPosition = pos;
                }
                else {
                    scrollRect.DOVerticalNormalizedPos(y, duration).SetEase(ease);
                }
            }
        }

        public static void DOFade(Object parent, string path, float duration, float alpha, Ease ease = Ease.OutQuad) {
            Graphic graphic = CommonUtil.GetComponent<Graphic>(parent, path);
            if (graphic != null) {
                if (duration == 0) {
                    Color color = graphic.color;
                    color.a = alpha;
                    graphic.color = color;
                }
                else {
                    graphic.DOFade(alpha, duration).SetEase(ease);
                }
            }
        }

        public static void DOColor(Object parent, string path, float duration, Color color, Ease ease = Ease.OutQuad) {
            Graphic graphic = CommonUtil.GetComponent<Graphic>(parent, path);
            if (graphic != null) {
                if (duration == 0) {
                    graphic.color = color;
                }
                else {
                    graphic.DOColor(color, duration).SetEase(ease);
                }
            }
        }

        public static void DOPunchPosition(Object parent, string path, float duration, Vector3 punch, int vibrato = 10, float elasticity = 1, bool snapping = false, Ease ease = Ease.OutQuad) {
            Transform transform = CommonUtil.GetTransform(parent, path);
            if (transform != null) {
                transform.DOPunchPosition(punch, duration, vibrato, elasticity, snapping).SetEase(ease);
            }
        }

        public static void DOPunchRotation(Object parent, string path, float duration, Vector3 punch, int vibrato = 10, float elasticity = 1, Ease ease = Ease.OutQuad) {
            Transform transform = CommonUtil.GetTransform(parent, path);
            if (transform != null) {
                transform.DOPunchRotation(punch, duration, vibrato, elasticity).SetEase(ease);
            }
        }

        public static void DOPunchScale(Object parent, string path, float duration, Vector3 punch, int vibrato = 10, float elasticity = 1, Ease ease = Ease.OutQuad) {
            Transform transform = CommonUtil.GetTransform(parent, path);
            if (transform != null) {
                transform.DOPunchScale(punch, duration, vibrato, elasticity).SetEase(ease);
            }
        }

        public static TweenerCore<float, float, FloatOptions> DOFadeCanvasGroup(CanvasGroup canvasGroup, float endValue, float duration) {
            return canvasGroup.DOFade(endValue, duration);
        }

    }
}
